package cn.tianwt.proxy.http.server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Map;

import cn.tianwt.proxy.Context;
import cn.tianwt.proxy.http.utils.LogUtils;
import cn.tianwt.proxy.http.utils.NetworkUtils;
import cn.tianwt.proxy.http.utils.Utils;

public class HttpProxyServer {
	
	private  Context context;
	private  ServerSocket mProxyServer;
	private  volatile  boolean isRunning = false;
	private  volatile  boolean isPause = false;
	
	public HttpProxyServer(Context context) {
		this.context = context;
	}

	public void start() throws IOException {
		
		try {
			Map<String, Object> localInetIdent = NetworkUtils.getLocalInetIdent();
			String ip = (String) localInetIdent.get("ip");
			int port = this.context.getPort();
			
			int maxConnect = (100*(Runtime.getRuntime().availableProcessors()*2+1));

			LogUtils.D("initilize: ip="+ip+", port="+port+", maxCount="+maxConnect);

			mProxyServer = new ServerSocket(port,maxConnect);
			mProxyServer.setSoTimeout((int) this.context.getTimeout());

			isRunning = true;
		} catch (Exception e) {
			e.printStackTrace();
			isRunning = false;
			Utils.closeQuiety(mProxyServer);
			mProxyServer = null;
			throw e;
		}
	}


	public void pause() {
		this.isPause = false;
	}


	public void destory() {
		
		this.isRunning = false;
		this.isPause = false;
		Utils.closeQuiety(mProxyServer);
	}
	
	public boolean isReay() {
		return mProxyServer!=null && mProxyServer.getLocalPort()!=0 && mProxyServer.isBound();
	}


	public boolean isRunning() {
		
		return isRunning;
	}

	public void run() {
		while(shouldWaitForConnect()) {
				Socket client = null;;
				try {
					client = mProxyServer.accept();
					if(!isPause) {
						Worker.startHandle(client);
					}else {
						Utils.closeQuiety(client);
					}
				}catch(Exception e) {
					if(!shouldWaitForConnect()) {
						Utils.closeQuiety(client);
						e.printStackTrace();
					}else {
						LogUtils.E(">>>>"+e.getLocalizedMessage());
						continue;
					}
				}
				
		}
		
		this.destory();
		
	}

	private boolean shouldWaitForConnect() {
		return isRunning && mProxyServer!=null && !mProxyServer.isClosed();
	}

	public boolean isPaused() {
		return isPause;
	}
	
	 
}
